#ifndef MineCraftBlockLibrary_H
#define MineCraftBlockLibrary_H

#include <QObject>
#include <QMap>
#include <QtQmlIntegration>
#include <QVariantList>
#include <QVector2D>
#include <QQmlContext>
#include <QtQml>

class MineCraftBlockLibrary;
struct BlockRegister;

//方块元数据
class BlockMeta:public QObject
{
    Q_OBJECT
    QML_ELEMENT
    QML_UNCREATABLE("")
public:
    enum BlockType{//方块的id
        None = 0,
        GrassBlock,//草方块
        StoneBlock,//石头方块
        DirtBlock,//泥土方块
        OakPlank,//橡木木板
        BrickBlock,//砖块
        TNTBlock,//TNT方块
        CobbleStonBlock,//圆石方块
        BedRockBlock,//基岩方块
        SandBlock,//沙子方块
        GravelBlock,//沙砾
        OakBlock,//橡木
        IronBlock,//铁块
        GoldBlock,//金块
        DiamondBlock,//钻石块
        GoldOre,//金矿
        IronOre,//铁矿
        CoalOre,//煤矿
        DiamondOre,//钻石矿
        RedstoneOre,//红石矿
        Anvil,//铁砧
        BigChest,//大箱子
        Chest,//箱子
        CobbleStoneFence1,//圆石栅栏
        CobbleStoneFence2,
        CobbleStoneFence3,
        EnderChest,//末影箱
        EndPortal,//末地传送门
        Fence1,//栅栏
        Fence2,
        Fence3,
        Ladder,//梯子
        Rail1,//铁轨
        Rail2,
        Torch,//火把
        TorchOnWall,//墙上的火把
        Vine,
        Bed//床
    };
    Q_ENUM(BlockType);

    typedef QList<QVector2D> FaceList;

    enum BlockAttribute{
        Empty = 0,
        Transparent = 0x1,//透明方块,意味着它的材质有透明的部分或是形状特殊使得无法将其后面的方块遮挡
        BlockShape = 0x2//是否是方块形状的
    };
    Q_DECLARE_FLAGS(BlockAttributes,BlockAttribute);
    Q_FLAG(BlockAttributes);

    FaceList faces() const;
    QUrl mesh() const;
    BlockType type() const;
    BlockAttributes attribute() const;


signals:
    void facesChanged();

    void meshChanged();
    void typeChanged();

    void attributeChanged();

private:
    void setFaces(const FaceList &newFaces);
    void setMesh(const QUrl &newMesh);
    void setType(const BlockType &newType);
    void setAttribute(const BlockAttributes &newAttribute);
private:
    BlockType m_type = None;
    BlockAttributes m_attribute = Empty;
    FaceList m_faces;//方块的面数据,只有完全方块形状有这个
    QUrl m_mesh;//方块的模型数据，非方块形状的有这个
    Q_PROPERTY(FaceList faces READ faces NOTIFY facesChanged FINAL)
    Q_PROPERTY(QUrl mesh READ mesh NOTIFY meshChanged FINAL)
    Q_PROPERTY(BlockType type READ type NOTIFY typeChanged FINAL)
    Q_PROPERTY(BlockAttributes attribute READ attribute NOTIFY attributeChanged FINAL)
    friend struct BlockRegister;
};

Q_DECLARE_OPERATORS_FOR_FLAGS(BlockMeta::BlockAttributes);

class MineCraftBlockLibrary:public QObject{
    Q_OBJECT
    QML_ELEMENT
    QML_SINGLETON
public:
    Q_INVOKABLE BlockMeta* getBlock(BlockMeta::BlockType type);

    static MineCraftBlockLibrary *create(QQmlEngine*,QJSEngine*);
    static MineCraftBlockLibrary* instance();
private:
    BlockRegister reg(BlockMeta::BlockType type);
    MineCraftBlockLibrary(int pri);
private:
    void registerBlocks();
    QUrl nativeMesh(QString name);
    friend struct BlockRegister;
    QMap<BlockMeta::BlockType,BlockMeta*> m_map;
};

struct BlockRegister
{
    BlockRegister(MineCraftBlockLibrary* origin,BlockMeta::BlockType type){
        this->origin = origin;
        m_ret.reset(new BlockMeta());
        m_ret->m_type = type;
    }

    BlockRegister(BlockRegister&& other)
    {
        origin = other.origin;
        m_ret = std::move(other.m_ret);
    }
    BlockRegister& faces(QList<QVector2D> faces);
    BlockRegister& mesh(QUrl mesh);
    BlockRegister& attr(BlockMeta::BlockAttribute attribute);


    BlockRegister& normal(QList<QVector2D> f);
    BlockRegister& triangleMesh(QUrl mesh);

    void finish();

    MineCraftBlockLibrary* origin;
    std::unique_ptr<BlockMeta> m_ret;
};



#endif
